﻿using System;
using System.Reflection;

namespace Aeon.Configuration
{
    /// <summary>
    /// Describes a drive configuration registration.
    /// </summary>
    public sealed class DriveConfigurationInfo
    {
        /// <summary>
        /// The type of the drive configuration.
        /// </summary>
        private Type configType;

        /// <summary>
        /// Initializes a new instance of the DriveConfigurationInfo class.
        /// </summary>
        /// <param name="configType">Type of the drive configuration.</param>
        internal DriveConfigurationInfo(Type configType)
        {
            var property = configType.GetProperty("Name", BindingFlags.Public | BindingFlags.Static | BindingFlags.GetProperty, null, typeof(string), new Type[0], null);
            if(property != null)
                this.Name = (string)property.GetValue(null, null) ?? string.Empty;
            else
                this.Name = configType.Name;

            var attrs = configType.GetCustomAttributes(typeof(DriveConfigurationAttribute), false);
            var configAttribute = (DriveConfigurationAttribute)attrs[0];
            if(!string.IsNullOrEmpty(configAttribute.Id))
                this.Id = configAttribute.Id;
            else
                this.Id = configType.FullName;

            this.configType = configType;
        }

        /// <summary>
        /// Gets the unique ID of the drive configuration.
        /// </summary>
        public string Id { get; private set; }
        /// <summary>
        /// Gets the localized name of the drive configuration.
        /// </summary>
        public string Name { get; private set; }
        /// <summary>
        /// Gets a value indicating whether the drive configuration has a view assigned to it.
        /// </summary>
        public bool HasView
        {
            get { return this.ViewType != null; }
        }
        /// <summary>
        /// Gets the type of the drive configuration.
        /// </summary>
        public Type ConfigType
        {
            get { return this.configType; }
        }
        /// <summary>
        /// Gets the type of the view used for editing this configuration type.
        /// </summary>
        public Type ViewType { get; internal set; }

        /// <summary>
        /// Returns a new instance of the default drive configuration.
        /// </summary>
        /// <returns>Default configuration for the drive.</returns>
        public IDriveConfiguration CreateConfiguration()
        {
            return (IDriveConfiguration)Activator.CreateInstance(this.configType);
        }
        /// <summary>
        /// Returns a new instance of a view for the drive configuration.
        /// </summary>
        /// <returns>New instance of a view for the drive configuration.</returns>
        public IDriveConfigurationView CreateView()
        {
            var type = this.ViewType;
            if(type != null)
                return (IDriveConfigurationView)Activator.CreateInstance(type);
            else
                return null;
        }
        /// <summary>
        /// Returns the localized name of the drive configuration.
        /// </summary>
        /// <returns>Localized name of the drive configuration.</returns>
        public override string ToString()
        {
            return this.Name;
        }
    }
}
